package org.lgiavedoni.android.franq.core.command;

import java.io.PrintWriter;
import java.io.StringWriter;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.UnrecognizedOptionException;
import org.lgiavedoni.android.franq.service.communication.CommunicationService;
import org.lgiavedoni.android.franq.service.log.Logger;
import org.lgiavedoni.android.franq.util.collection.CollectionUtils;

public abstract class Command {

	private final Options options = new Options();

	private static final CommandLineParser parser = new GnuParser();

	private static final String OPTION_HELP = "help";
	private static final String OPTION_HELP2 = "?";

	public Command() {
		options.addOption(OPTION_HELP, false, "Help");
		options.addOption(OPTION_HELP2, false, "Help");
		setOptions(options);
	}

	public abstract String getCommandText();

	public String getHelpText() {
		try {
			StringWriter sw = new StringWriter();
			HelpFormatter formatter = new HelpFormatter();
			// formatter.printHelp(getCommandText(), options);
			formatter.printHelp(new PrintWriter(sw), formatter.getWidth(), getCommandText(), null, options, formatter.getLeftPadding(), formatter.getDescPadding(), null);
			return sw.toString();
		} catch (Exception e) {
			Logger.inst.error(e);
		}
		return "Sorry, help is not available for this command";
	}

	public void execute(String[] params) throws Exception {
		params = CollectionUtils.removeElement(params, 0);

		try {
			CommandLine cmd = parser.parse(options, params);

			if (cmd.hasOption(OPTION_HELP) || cmd.hasOption(OPTION_HELP2)) {
				CommunicationService.inst.sendDefaultTextMessage(getHelpText());
			} else if (!execute(cmd)) {
				CommunicationService.inst.sendDefaultTextMessage(getHelpText());
			}
		} catch (UnrecognizedOptionException ue) {
			CommunicationService.inst.sendDefaultTextMessage(getHelpText());
		}
	}

	protected abstract boolean execute(CommandLine cmd) throws Exception;

	protected void setOptions(Options options) {
	}

	public void sendText(String text) {
		CommunicationService.inst.sendDefaultTextMessage(text);
	}

}
